<template>
  <div class="common-layout">
    <div class="auth-container">
      <a class="header" id="header-title" @click="clickHeader"
        >学生选课系统登录</a
      >
      <div class="auth-card">
        <div class="auth-tabs">
          <button
            @click="activeTab = 'login'"
            :class="{ active: activeTab === 'login' }"
          >
            登录
          </button>
          <button
            @click="activeTab = 'register'"
            :class="{ active: activeTab === 'register' }"
          >
            注册
          </button>
        </div>
        <!-- 登录表单 -->
        <div v-if="activeTab === 'login'" class="auth-form">
          <el-form
            label-position="top"
            :model="loginForm"
            :rules="loginRules"
            ref="loginFormRef"
          >
            <el-form-item label="学号/教师号">
              <el-input
                v-model="loginForm.userId"
                placeholder="请输入学号/教师号"
              />
            </el-form-item>
            <el-form-item label="密码">
              <el-input
                v-model="loginForm.password"
                type="password"
                placeholder="请输入密码"
                show-password
              />
            </el-form-item>
            <div>
              <div class="form-options">
                <div class="remember-me">
                  <el-checkbox v-model="rememberMe">记住我</el-checkbox>
                </div>
                <el-button type="primary" link @click="showResetPassword = true"
                  >重置密码</el-button
                >
              </div>
            </div>
            <el-form-item>
              <el-button type="primary" @click="handleLogin" style="width: 100%"
                >登录</el-button
              >
            </el-form-item>
          </el-form>
        </div>
        <!-- 注册表单 -->
        <div v-if="activeTab === 'register'" class="auth-form">
          <div class="role-selector">
            <el-radio-group v-model="roleRadio">
              <el-radio-button label="学生" :value="UserRoleEnum.STUDENT" />
              <el-radio-button label="教师" :value="UserRoleEnum.TEACHER" />
            </el-radio-group>
          </div>

          <!-- 学生注册表单 -->
          <el-form
            v-if="roleRadio === UserRoleEnum.STUDENT"
            :model="registerStudentForm"
            :rules="studentRegisterRules"
            label-position="top"
            ref="studentRegisterFormRef"
          >
            <el-row :gutter="20">
              <el-col :span="12">
                <!-- 学号 -->
                <el-form-item label="学号" prop="studentId">
                  <el-input
                    v-model="registerStudentForm.studentId"
                    placeholder="请输入学号"
                    clearable
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <!-- 学生姓名 -->
                <el-form-item label="学生姓名" prop="studentName">
                  <el-input
                    v-model="registerStudentForm.studentName"
                    placeholder="请输入学生姓名"
                    clearable
                  />
                </el-form-item>
              </el-col>
            </el-row>

            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="性别" prop="gender">
                  <el-select v-model="registerStudentForm.gender">
                    <el-option label="男" value="男" />
                    <el-option label="女" value="女" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="手机号" prop="phone">
                  <el-input
                    v-model="registerStudentForm.phone"
                    placeholder="请输入手机号"
                  />
                </el-form-item>
              </el-col>
            </el-row>

            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="出生日期" prop="birthDate">
                  <el-date-picker
                    v-model="registerStudentForm.birthDate"
                    type="date"
                    placeholder="请选择出生日期"
                    style="width: 100%"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="入学日期" prop="enrollmentDate">
                  <el-date-picker
                    v-model="registerStudentForm.enrollmentDate"
                    type="date"
                    placeholder="请选择入学日期"
                    style="width: 100%"
                  />
                </el-form-item>
              </el-col>
            </el-row>

            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="班级号" prop="classId">
                  <el-input-number
                    v-model="registerStudentForm.classId"
                    :min="1"
                    :max="1000"
                    style="width: 100%"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="所属学院" prop="deptId">
                  <el-input-number
                    v-model="registerStudentForm.deptId"
                    :min="1"
                    :max="1000"
                    style="width: 100%"
                  />
                </el-form-item>
              </el-col>
            </el-row>

            <el-form-item label="邮箱" prop="email">
              <el-input
                v-model="registerStudentForm.email"
                type="email"
                placeholder="请输入邮箱"
                clearable
              />
            </el-form-item>

            <el-form-item label="家庭住址" prop="address">
              <el-input
                v-model="registerStudentForm.address"
                placeholder="请输入家庭住址"
              />
            </el-form-item>

            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="密码" prop="password">
                  <el-input
                    v-model="registerStudentForm.password"
                    type="password"
                    placeholder="请输入密码"
                    show-password
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="确认密码" prop="confirmPassword">
                  <el-input
                    v-model="registerStudentForm.confirmPassword"
                    type="password"
                    placeholder="请再次输入密码"
                    show-password
                  />
                </el-form-item>
              </el-col>
            </el-row>

            <el-form-item>
              <el-button
                type="primary"
                style="width: 100%"
                @click="handleRegister"
              >
                注册
              </el-button>
            </el-form-item>
          </el-form>

          <!-- 教师注册表单 -->
          <el-form
            v-if="roleRadio === UserRoleEnum.TEACHER"
            :model="registerTeacherForm"
            :rules="teacherRegisterRules"
            label-position="top"
            ref="teacherRegisterFormRef"
          >
            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="教师号" prop="teacherId">
                  <el-input
                    v-model="registerTeacherForm.teacherId"
                    placeholder="请输入教师号"
                    clearable
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="教师姓名" prop="teacherName">
                  <el-input
                    v-model="registerTeacherForm.teacherName"
                    placeholder="请输入教师姓名"
                    clearable
                  />
                </el-form-item>
              </el-col>
            </el-row>

            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="性别" prop="gender">
                  <el-select v-model="registerTeacherForm.gender">
                    <el-option label="男" value="男" />
                    <el-option label="女" value="女" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="职称" prop="title">
                  <el-input
                    v-model="registerTeacherForm.title"
                    placeholder="请输入职称"
                  />
                </el-form-item>
              </el-col>
            </el-row>

            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="出生日期" prop="birthDate">
                  <el-date-picker
                    v-model="registerTeacherForm.birthDate"
                    type="date"
                    placeholder="请选择出生日期"
                    style="width: 100%"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="入职日期" prop="hireDate">
                  <el-date-picker
                    v-model="registerTeacherForm.hireDate"
                    type="date"
                    placeholder="请选择入职日期"
                    style="width: 100%"
                  />
                </el-form-item>
              </el-col>
            </el-row>

            <el-row :gutter="20">
              <el-col :span="24">
                <el-form-item label="所属学院" prop="deptId">
                  <el-input-number
                    v-model="registerTeacherForm.deptId"
                    :min="1"
                    :max="1000"
                    style="width: 100%; text-align: center"
                  />
                </el-form-item>
              </el-col>
            </el-row>

            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="手机号" prop="phone">
                  <el-input
                    v-model="registerTeacherForm.phone"
                    placeholder="请输入手机号"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="邮箱" prop="email">
                  <el-input
                    v-model="registerTeacherForm.email"
                    type="email"
                    placeholder="请输入邮箱"
                    clearable
                  />
                </el-form-item>
              </el-col>
            </el-row>

            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="密码" prop="password">
                  <el-input
                    v-model="registerTeacherForm.password"
                    type="password"
                    placeholder="请输入密码"
                    show-password
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="确认密码" prop="confirmPassword">
                  <el-input
                    v-model="registerTeacherForm.confirmPassword"
                    type="password"
                    placeholder="请再次输入密码"
                    show-password
                  />
                </el-form-item>
              </el-col>
            </el-row>

            <el-form-item>
              <el-button
                type="primary"
                style="width: 100%"
                @click="handleRegister"
              >
                注册
              </el-button>
            </el-form-item>
          </el-form>
        </div>
        <!-- 重置密码 -->
        <el-dialog
          v-model="showResetPassword"
          title="重置密码"
          style="width: 30%"
        >
          <el-form
            :model="resetPasswordForm"
            :rules="resetPasswordRules"
            label-position="top"
            ref="resetPasswordFormRef"
          >
            <el-form-item label="学号/教师号" prop="userId">
              <el-input
                v-model="resetPasswordForm.userId"
                placeholder="请输入学号/教师号"
                autocomplete="off"
                clearable
              />
            </el-form-item>
            <el-form-item label="旧密码" prop="oldPassword">
              <el-input
                v-model="resetPasswordForm.oldPassword"
                placeholder="请输入旧密码"
                type="password"
                show-password
                autocomplete="off"
                clearable
              />
            </el-form-item>
            <el-form-item label="新密码" prop="newPassword">
              <el-input
                v-model="resetPasswordForm.newPassword"
                placeholder="请输入新密码"
                type="password"
                show-password
                autocomplete="off"
                clearable
              />
            </el-form-item>
            <el-form-item>
              <el-button
                type="warning"
                style="width: 100%"
                @click="handleResetPassword"
                >重置密码</el-button
              >
            </el-form-item>
          </el-form>
        </el-dialog>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { reactive, ref } from "vue";
import { useRouter } from "vue-router";
import { ElMessage, type FormRules, type FormInstance } from "element-plus";
import { validatePassword } from "@/utils/passwordValidator";
import { authApi } from "@/api";
import { saveAuthData } from "@/auth";
import type {
  ChangePasswordForm,
  Student,
  Teacher,
  User
} from "@/types/api-types";
import { UserRoleEnum } from "@/types/global-types.d";

const router = useRouter();
const activeTab = ref("login");
const showResetPassword = ref(false);
const rememberMe = ref(false);

// 表单引用
const loginFormRef = ref<FormInstance>();
const studentRegisterFormRef = ref<FormInstance>();
const teacherRegisterFormRef = ref<FormInstance>();
const resetPasswordFormRef = ref<FormInstance>();

// 登录表单
const loginForm = ref({
  userId: "",
  password: ""
});

// 角色选择
const roleRadio = ref(UserRoleEnum.STUDENT);

// 学生注册表单
const registerStudentForm = reactive<Student>({
  studentId: "",
  studentName: "",
  gender: "男",
  birthDate: "",
  enrollmentDate: "",
  deptId: 0,
  classId: 0,
  phone: "",
  email: "",
  address: "",
  password: "",
  confirmPassword: ""
});

// 教师注册表单
const registerTeacherForm = reactive<Teacher>({
  teacherId: "",
  teacherName: "",
  gender: "男",
  birthDate: "",
  hireDate: "",
  deptId: 0,
  title: "",
  phone: "",
  email: "",
  password: "",
  confirmPassword: ""
});

// 重置密码表单
const resetPasswordForm = ref<ChangePasswordForm>({
  userId: "",
  oldPassword: "",
  newPassword: ""
});

// 密码校验器
const passwordValidator = (rule: any, value: string, callback: any) => {
  const PASSWORD_REG =
    /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]{8,20}/;
  if (!value) {
    callback(new Error("密码不能为空"));
  } else if (value.length > 20 || value.length < 8) {
    callback(new Error("密码长度应该介于8到20位之间"));
  } else if (!PASSWORD_REG.test(value)) {
    callback(new Error("密码应该同时包含大小写字母、数字、特殊字符，长度8~20"));
  } else {
    callback();
  }
};

// 确认密码校验器
const confirmPasswordValidator = (rule: any, value: string, callback: any) => {
  const form = rule.field.includes("student")
    ? registerStudentForm
    : registerTeacherForm;
  if (form.confirmPassword !== form.password) {
    callback(new Error("两次输入的密码不一致"));
  } else {
    callback();
  }
};

// 邮箱校验器
const emailValidator = (rule: any, value: string, callback: any) => {
  const EMAIL_REG =
    /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z]{2,4})+$/;
  if (!value) {
    callback(new Error("邮箱不能为空"));
  } else if (value.length > 50 || value.length < 10) {
    callback(new Error("邮箱长度应该介于10到50位之间"));
  } else if (!EMAIL_REG.test(value)) {
    callback(new Error("邮箱格式不符合标准"));
  } else {
    callback();
  }
};

// 登录表格验证规则
const loginRules = reactive<FormRules<User>>({
  userId: [
    { required: true, message: "请输入用户id", trigger: "blur" },
    { max: 20, message: "长度不应超过20位字符", trigger: "blur" }
  ],
  password: [{ validator: passwordValidator, trigger: "blur" }]
});

// 学生注册表格验证规则
const studentRegisterRules = reactive<FormRules<Student>>({
  studentId: [
    { required: true, message: "请输入学号", trigger: "blur" },
    { max: 20, message: "长度不应超过20位字符", trigger: "blur" }
  ],
  studentName: [
    { required: true, message: "学生姓名不能为空", trigger: "blur" },
    { max: 20, message: "长度不应超过20位字符", trigger: "blur" }
  ],
  password: [{ validator: passwordValidator, trigger: "blur" }],
  confirmPassword: [{ validator: confirmPasswordValidator, trigger: "blur" }],
  email: [{ validator: emailValidator, trigger: "blur" }],
  phone: [
    {
      pattern: /^1[3-9]\d{9}$/,
      message: "请输入正确的手机号码",
      trigger: "blur"
    }
  ]
});

// 教师注册表格验证规则
const teacherRegisterRules = reactive<FormRules<Teacher>>({
  teacherId: [
    { required: true, message: "请输入教师号", trigger: "blur" },
    { max: 20, message: "长度不应超过20位字符", trigger: "blur" }
  ],
  teacherName: [
    { required: true, message: "教师姓名不能为空", trigger: "blur" },
    { max: 20, message: "长度不应超过20位字符", trigger: "blur" }
  ],
  password: [{ validator: passwordValidator, trigger: "blur" }],
  confirmPassword: [{ validator: confirmPasswordValidator, trigger: "blur" }],
  email: [{ validator: emailValidator, trigger: "blur" }],
  phone: [
    {
      pattern: /^1[3-9]\d{9}$/,
      message: "请输入正确的手机号码",
      trigger: "blur"
    }
  ]
});

// 重置密码验证规则
const resetPasswordRules = reactive<FormRules<ChangePasswordForm>>({
  userId: [
    { required: true, message: "请输入用户id", trigger: "blur" },
    { min: 4, max: 20, message: "长度不应超过20位字符", trigger: "blur" }
  ],
  oldPassword: [{ required: true, message: "旧密码不能为空", trigger: "blur" }],
  newPassword: [{ validator: passwordValidator, trigger: "blur" }]
});

/**
 * 验证userId有效性
 */
const validateUserId = (userId: string | number): boolean => {
  userId = String(userId);
  if (!userId) {
    ElMessage.error("id不能为空");
    return false;
  }
  const l = userId.length;
  if (l > 20 || l < 4) {
    ElMessage.error("id长度应该介于4和20之间");
    return false;
  }
  return true;
};

/**
 * 处理登录
 */
const handleLogin = async () => {
  if (!loginFormRef.value) return;

  try {
    await loginFormRef.value.validate();

    const { isValid, errors } = validatePassword(loginForm.value.password);

    if (!isValid) {
      ElMessage.error(errors.join("，"));
      return;
    }

    if (!validateUserId(loginForm.value.userId)) {
      return;
    }

    const response = await authApi.login(loginForm.value);
    const { code, data } = response;

    if (code >= 200 && code < 300) {
      saveAuthData(data);
    }

    gracefulReload(); // 重新加载，替换浏览器原有信息
    router.replace("/home");
    ElMessage.success("登录成功");
  } catch (error) {
    ElMessage.error("登录失败");
    console.error("登录失败", error);
  }
};

/**
 * 处理注册
 */
const handleRegister = async () => {
  try {
    if (roleRadio.value === UserRoleEnum.STUDENT) {
      await studentRegisterFormRef.value?.validate();

      // 移除确认密码字段
      const { confirmPassword, ...submitData } = registerStudentForm;
      await authApi.registerStudent(submitData);
    } else {
      await teacherRegisterFormRef.value?.validate();

      // 移除确认密码字段
      const { confirmPassword, ...submitData } = registerTeacherForm;
      await authApi.registerTeacher(submitData);
    }

    ElMessage.success("注册成功，请登录");
    activeTab.value = "login";

    // 重置注册表单
    if (roleRadio.value === UserRoleEnum.STUDENT) {
      Object.assign(registerStudentForm, {
        studentId: "",
        studentName: "",
        gender: "男",
        birthDate: "",
        enrollmentDate: "",
        deptId: 0,
        classId: 0,
        phone: "",
        email: "",
        address: "",
        password: "",
        confirmPassword: ""
      });
    } else {
      Object.assign(registerTeacherForm, {
        teacherId: "",
        teacherName: "",
        gender: "男",
        birthDate: "",
        hireDate: "",
        deptId: 0,
        title: "",
        phone: "",
        email: "",
        password: "",
        confirmPassword: ""
      });
    }
  } catch (error) {
    ElMessage.error("注册失败");
    console.error("注册失败：", error);
  }
};

/**
 * 处理重置密码功能
 */
const handleResetPassword = async () => {
  if (!resetPasswordFormRef.value) return;

  try {
    await resetPasswordFormRef.value.validate();

    await authApi.changePassword(resetPasswordForm.value);
    ElMessage.success("密码重置成功，请回登录页面登录");
    showResetPassword.value = false;
  } catch (error) {
    console.error("重置密码失败", error);
    ElMessage.error("密码重置失败，请检查输入内容");
  }
};

/**
 * 点击标题效果
 */
const clickHeader = () => {
  const header = document.getElementById("header-title");
  const text = header?.textContent as string;
  if (header) {
    header.textContent = "YOUR LIFE STARTS HERE!";
    setTimeout(() => {
      header.textContent = text;
    }, 2000);
  }
};

const showLoading = ref(false);

// 先显示加载动画再刷新
const gracefulReload = () => {
  showLoading.value = true;
  setTimeout(() => {
    window.location.reload();
  }, 500);
};
</script>

<style lang="scss" scoped>
.common-layout {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-image: url("@/assets/images/college_at_night.jpg");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  z-index: 0;
}

.header {
  font-size: 60px;
  font-weight: bold;
  color: white;
  position: fixed;
  top: 70px;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  max-width: 800px;
  text-align: center;
  transition: all 0.3s ease;
  cursor: pointer;
  justify-content: center;
}

.header:hover {
  transform: translateX(-50%) scale(1.2);
}

.auth-container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
  width: 100vw;
  position: relative;
}

.auth-card {
  z-index: 1;
  background: white;
  border-radius: 15px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  width: 500px;
  padding: 30px;
  position: relative;
}

.auth-tabs {
  display: flex;
  margin-bottom: 20px;
  border-bottom: 1px solid #eee;
}

.auth-tabs button {
  flex: 1;
  padding: 10px;
  background: none;
  border: none;
  cursor: pointer;
  font-size: 16px;
  color: #666;
  position: relative;
}

.auth-tabs button.active {
  color: #3498db;
  font-weight: bold;
}

.auth-tabs button.active::after {
  content: "";
  position: absolute;
  bottom: -1px;
  left: 0;
  right: 0;
  height: 2px;
  background: #3498db;
}

.form-options {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 15px 0;
  font-size: 14px;
}

.role-selector {
  margin-bottom: 20px;
  text-align: center;
}

.el-form-item {
  margin-bottom: 18px;
}

.el-row {
  margin-bottom: 0;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
</style>
